{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "44c5fd0b-ddd1-44e7-b049-192834d7cfdc",
   "metadata": {},
   "source": [
    "# 多层网络模型\n",
    "\n",
    "本小节主要介绍单层神经网络模型的设计，使用LeNet5的变体作为讲解实例。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c057252-2f59-49d2-81d2-b3305907fea5",
   "metadata": {},
   "source": [
    "首先需要导入所需的minspore包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2648658b-b0f2-497f-9370-8542e5fe655e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import mindspore.nn as nn\n",
    "from mindspore.common.initializer import Normal"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17c03413-0a59-4c15-81ef-b659b68403a2",
   "metadata": {},
   "source": [
    "其次定义单层网络，在定义中，我们将所需的运算设置为卷积，dense，maxpool等多层。在构建前向网络时，构建多层卷积，relu激活函数和flatten等得到定义好的模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7797494c-a515-4590-b962-089253b0fe80",
   "metadata": {},
   "outputs": [],
   "source": [
    "class LeNet5(nn.Cell):\n",
    "    \"\"\"\n",
    "    Lenet网络结构\n",
    "    \"\"\"\n",
    "    def __init__(self, num_class=10, num_channel=1):\n",
    "        super(LeNet5, self).__init__()\n",
    "        # 定义所需要的运算\n",
    "        self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')\n",
    "        self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')\n",
    "        self.fc1 = nn.Dense(16 * 5 * 5, 120)\n",
    "        self.fc2 = nn.Dense(120, 84)\n",
    "        self.fc3 = nn.Dense(84, num_class)\n",
    "        self.relu = nn.ReLU()\n",
    "        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        self.flatten = nn.Flatten()\n",
    "\n",
    "    def construct(self, x):\n",
    "        # 使用定义好的运算构建前向网络\n",
    "        x = self.conv1(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.max_pool2d(x)\n",
    "        x = self.conv2(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.max_pool2d(x)\n",
    "        x = self.flatten(x)\n",
    "        x = self.fc1(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.fc2(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.fc3(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27db438f-a2c6-48bf-9864-70d85002c046",
   "metadata": {},
   "source": [
    "对模型进行调用，得到结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "26f7ace5-2921-4835-82c0-ab778d598631",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('conv1.weight', Parameter (name=conv1.weight, shape=(6, 1, 5, 5), dtype=Float32, requires_grad=True))\n",
      "('conv2.weight', Parameter (name=conv2.weight, shape=(16, 6, 5, 5), dtype=Float32, requires_grad=True))\n",
      "('fc1.weight', Parameter (name=fc1.weight, shape=(120, 400), dtype=Float32, requires_grad=True))\n",
      "('fc1.bias', Parameter (name=fc1.bias, shape=(120,), dtype=Float32, requires_grad=True))\n",
      "('fc2.weight', Parameter (name=fc2.weight, shape=(84, 120), dtype=Float32, requires_grad=True))\n",
      "('fc2.bias', Parameter (name=fc2.bias, shape=(84,), dtype=Float32, requires_grad=True))\n",
      "('fc3.weight', Parameter (name=fc3.weight, shape=(10, 84), dtype=Float32, requires_grad=True))\n",
      "('fc3.bias', Parameter (name=fc3.bias, shape=(10,), dtype=Float32, requires_grad=True))\n"
     ]
    }
   ],
   "source": [
    "model = LeNet5()\n",
    "for m in model.parameters_and_names():\n",
    "    print(m)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "MindSpore",
   "language": "python",
   "name": "mindspore"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
